﻿/*
    Alunos:
        Jorge Luis Stefanelli Bonafé	5889794
        Marcelo Koti Kamada             7277670
*/

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    char sIn[10];
    int col, row, maxColor;

    scanf("%s",sIn);          // Lê a primeira linha do input, para saber se o arquivo e' P3 ou P6
    scanf("%d%d",&col,&row);  // Lê Nº de colunas e de linhas
    scanf("%d",&maxColor);    // Lê valor máximo de cor (não usado)

    // Inicializa as matrizes de R, G e B da imagem resultante.
    int **Rout = (int**) malloc(sizeof(int*) * row);
    int **Gout = (int**) malloc(sizeof(int*) * row);
    int **Bout = (int**) malloc(sizeof(int*) * row);

    int i;
    for(i = 0; i < row; i ++) {
        Rout[i] = (int*) malloc(sizeof(int) * col);
        Gout[i] = (int*) malloc(sizeof(int) * col);
        Bout[i] = (int*) malloc(sizeof(int) * col);
    }

    // Inicializa as matrizes de R, G e B da imagem de input
    // Essas matrizes tem 4 linhas e colunas extras para armazenar -1 nas bordas.
    row = row + 4;
    col = col + 4;

    int **R = (int**) malloc(sizeof(int*) * row);
    int **G = (int**) malloc(sizeof(int*) * row);
    int **B = (int**) malloc(sizeof(int*) * row);

    for(i = 0; i < row; i ++) {
        R[i] = (int*) malloc(sizeof(int) * col);
        G[i] = (int*) malloc(sizeof(int) * col);
        B[i] = (int*) malloc(sizeof(int) * col);
    }

    // Coloca -1 nas bordas da esquerda e da direita, precisamos destes -1 apenas em uma matriz
    // para saber quando estamos trabalhando nos pixeis da borda
    for(i = 0; i < row; i++) {
        R[i][0] = -1;
        R[i][1] = -1;
        R[i][col-1] = -1;
        R[i][col-2] = -1;
    }

    // Coloca -1 nas bordas de cima e de baixo
    for(i = 0; i < col; i++) {
        R[0][i] = -1;
        R[1][i] = -1;
        R[row-1][i] = -1;
        R[row-2][i] = -1;
    }

    // Le a imagem de entrada
    int j;
    for(i = 2; i < row -2; i++) {
      for(j = 2; j < col-2; j++) {
          scanf("%d", &R[i][j]);
          scanf("%d", &G[i][j]);
          scanf("%d", &B[i][j]);
      }
    }

    // Processa a imagem
    // Nas bordas, alguns pixels adjacentes valem -1 (fora da imagem).
    // Esses pixels não são levados em conta no cálculo da média.
    // nDiv é o número total de pixels válidos, que é também
    // o valor da divisão na média aritmetica.
    int cAdj;                   //valor da coluna do pixel adjacente ao processado
    int rAdj;                   //valor da linha do pixel adjacente ao processado
    int totalR, totalG, totalB; //Valor total da soma dos 5x5 pixels para cada componente de cor
    int nDiv;

    for(i = 2; i < row-2; i++) {
        for(j = 2; j < col-2; j++) {
            totalR = 0;
            totalG = 0;
            totalB = 0;
            nDiv = 0;
            for(rAdj = i - 2; rAdj <= i + 2; rAdj++) {
                for(cAdj = j - 2; cAdj <= j + 2; cAdj++) {
                    if(R[rAdj][cAdj] >= 0) {
                        totalR += R[rAdj][cAdj];
                        totalG += G[rAdj][cAdj];
                        totalB += B[rAdj][cAdj];
                        nDiv++;
                    }
                }
            }
            Rout[i-2][j-2] = totalR/nDiv;
            Gout[i-2][j-2] = totalG/nDiv;
            Bout[i-2][j-2] = totalB/nDiv;
        }
    }

    // Imprime o arquivo de saida
    row = row - 4;
    col = col - 4;

    printf("P3\n");
    printf("%d %d\n%d\n",col,row,maxColor);

    for(i = 0; i < row; i++) {
        for(j = 0; j < col; j++) {
          printf("%d ",Rout[i][j]);
          printf("%d ",Gout[i][j]);
          printf("%d ",Bout[i][j]);
        }
        printf("\n");
    }

	// desalocacao de memoria
    free(R);
    free(G);
    free(B);
    free(Rout);
    free(Gout);
    free(Bout);

    return 0;
}
